[AWS CDK] スタックデプロイ時に `AlreadyExistsException: ChangeSet cdk-deploy-change-set cannot be created due to a mismatch with existing attribute ClientToken` というエラーが発生する場合の対処

[AWS CDK] スタックデプロイ時に `AlreadyExistsException: ChangeSet cdk-deploy-change-set cannot be created due to a mismatch with existing attribute ClientToken` というエラーが発生する場合の対処

Clock Icon2023.06.09

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部 Delivery部の若槻です。

今回は、AWS CDK のスタックデプロイ時に AlreadyExistsException: ChangeSet cdk-deploy-change-set cannot be created due to a mismatch with existing attribute ClientToken というエラーが発生したので、原因と対処方法について調べてみました。

事象

CI/CD ワークフロー(GitHub Actions)から AWS CDK を使ってスタックのデプロイを行うと、以下のようなエラーが発生しました。

cdkSampleStack failed: AlreadyExistsException: ChangeSet cdk-deploy-change-set cannot be created due to a mismatch with existing attribute ClientToken

(日本語訳)
既存の属性 ClientToken との不一致のため、ChangeSet cdk-deploy-change-set を作成できません

原因

原因は、同じ CDK スタックに対して複数の cdk deploy を同時に実行したことでした。

AWS CDK は、デプロイの一部として AWS CloudFormation の ChangeSet(変更セット)を作成し、実行した後に削除する処理を行います。

その ChangeSetは既定では cdk-deploy-change-set という固定の名前となるようです。

さらに次のドキュメントを確認すると、既存の ChangeSet に対して CreateChangeSet を実行する場合は、その既存の ChangeSet の ClientToken をリクエストパラメーターで指定することにより、CreateChangeSet の再試行をリクエストできます。

ClientToken
A unique identifier for this CreateChangeSet request. Specify this token if you plan to retry requests so that AWS CloudFormation knows that you're not attempting to create another change set with the same name. You might retry CreateChangeSet requests to ensure that AWS CloudFormation successfully received them.

(日本語訳)
この CreateChangeSet リクエストの一意の識別子。リクエストを再試行する予定がある場合は、このトークンを指定して、同じ名前で別の変更セットを作成しようとしていないことを AWS CloudFormation に認識させます。 CreateChangeSet リクエストを再試行して、AWS CloudFormation がリクエストを正常に受信したことを確認できます。

よって、後から実行した cdk deploy が、先に実行した cdk deploy の ChangeSet に対して、ClientToken を指定せずに CreateChangeSet をリクエストしたため、エラーが発生したと考えられます。

考えうる対処方法

CI/CD でキューイングを設定する

使用している CI/CD ツールでキューイングの設定をすることにより回避できる場合があります。

GitHub Actions であれば コンカレンシーグループ を使うことによりワークフローの同時実行数を制御することができます。

ただし、当然ですが各開発メンバーのローカル環境からの手動デプロイを制御することは出来ないため、開発メンバーが多いプロダクトの場合などは発生する可能性があります。

デプロイ時に変更セットを使用しないようにする

cdk deploy コマンドの --method パラメーターを使うことにより、デプロイ時に変更セットを使用しないようにすることができます。

cdk deploy --method=direct

プログレスバーが表示されないというデメリットがありますが、変更セットの重複の回避と同時に、デプロイの高速化が期待できます。

作成される変更セットの名前を変更する

--change-set-name パラメーターを指定することにより、作成される変更セットの名前を変更することができます。

cdk deploy --method=prepare-change-set --change-set-name MyChangeSetName

変更セットの名前を cdk deploy ごとにユニークな名前にすることで、変更セットの重複の回避ができます。

おわりに

AWS CDK のスタックデプロイ時に AlreadyExistsException: ChangeSet cdk-deploy-change-set cannot be created due to a mismatch with existing attribute ClientToken というエラーが発生したので、原因と対処方法について調べてみました。

そもそも同じスタックに対するデプロイの重複が頻繁に発生してしまう場合は、スタックの適切な分離が出来ていないか、プロジェクトにおける開発タスクの調整が適切に行われていない可能性があるので、そちらの見直しも検討してみると良いかもしれません。

以上

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.